/**
 * @file falling_edge.c
 * @author your name (you@domain.com)
 * @brief 下降沿检测器,用于检测输入信号的下降沿
 * @version 0.1
 * @date 2025-04-09
 *
 * @copyright Copyright (c) 2025
 *
 */

#include "falling_edge.h"

// 初始化检测器
void init_falling_detector(FallingEdgeDetector *detector,
                           FallingEdgeMonitor *buffer, size_t capacity) {
  detector->monitors = buffer;
  detector->count = 0;
  detector->capacity = capacity;
}

// 动态绑定一个变量
int bind_falling_variable(FallingEdgeDetector *detector, uint8_t *variable) {
  if (detector->count >= detector->capacity) {
    return -1; // 容量不足，绑定失败
  }

  FallingEdgeMonitor *monitor = &detector->monitors[detector->count];
  monitor->variable = variable;
  monitor->last_state = *variable;
  monitor->falling_trigger = 0;
  monitor->debounce_count = 0;
  monitor->debounce_limit = 10; // 默认连续10次采样确认，值可调整
  detector->count++;

  return 0; // 绑定成功
}

// 检测所有绑定变量的下降沿并更新触发状态（带去抖动）
void detect_falling_edges(FallingEdgeDetector *detector) {
  for (size_t i = 0; i < detector->count; i++) {
    FallingEdgeMonitor *monitor = &detector->monitors[i];
    uint8_t current_state = *(monitor->variable);

    if (monitor->last_state == 1 && current_state == 0) {
      // 检测到潜在下降沿，开始去抖计数
      if (monitor->debounce_count < monitor->debounce_limit) {
        monitor->debounce_count++;
      }
      if (monitor->debounce_count >= monitor->debounce_limit) {
        monitor->falling_trigger = 1; // 下降沿确认触发
      }
    } else {
      // 状态未保持稳定，重置计数器和触发标志
      monitor->falling_trigger = 0;
      monitor->debounce_count = 0;
    }

    // 更新状态
    monitor->last_state = current_state;
  }
}

// 根据变量地址查询下降沿是否触发
uint8_t is_falling_edge_triggered(FallingEdgeDetector *detector,
                                  uint8_t *variable) {
  for (size_t i = 0; i < detector->count; i++) {
    if (detector->monitors[i].variable == variable) {
      return detector->monitors[i].falling_trigger;
    }
  }
  return 0; // 未找到该变量，返回未触发
}

// 示例用法
#ifdef EXAMPLE_MAIN
#include <stdio.h>

int main(void) {
  uint8_t button1 = 1, button2 = 1; // 初始化为1以模拟下降沿

  FallingEdgeMonitor buffer[2];
  FallingEdgeDetector detector;
  init_detector(&detector, buffer, 2);

  bind_variable(&detector, &button1);
  bind_variable(&detector, &button2);

  // 模拟信号变化（带抖动）
  button1 = 0; // 第一次下降
  detect_falling_edges(&detector);
  printf("Button1: %d\n",
         is_falling_edge_triggered(&detector, &button1)); // 未触发

  button1 = 1; // 抖动
  detect_falling_edges(&detector);
  button1 = 0; // 再次下降
  detect_falling_edges(&detector);

  // 模拟多次稳定采样
  for (int i = 0; i < 10; i++) {
    detect_falling_edges(&detector);
    printf("Button1: %d\n", is_falling_edge_triggered(&detector, &button1));
  }

  button2 = 0; // button2 下降
  for (int i = 0; i < 10; i++) {
    detect_falling_edges(&detector);
  }
  printf("Button2: %d\n",
         is_falling_edge_triggered(&detector, &button2)); // 触发

  return 0;
}
#endif
